package thread.unit2.exetend;

import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程安全问题:
 * 有两个银行客户 同时向同一个账户 存入三次1000元.每次存完打印账户余额。
 *
 *     分析：
 *  1.是否是多线程问题？ 是，两个储户线程
 *  2.是否有共享数据？ 有，账户（或账户余额）
 *  3.是否有线程安全问题？有
 *  4.需要考虑如何解决线程安全问题？同步机制：有三种方式。
 *
 */
public class AccountTest {
    public static void main(String[] args) {
        Account account = new Account();
        Consumer c1 = new Consumer(account);
        Consumer c2 = new Consumer(account);
        c1.setName("张三");
        c2.setName("李四");
        c1.start();
        c2.start();
    }
}

//账户类
class Account {
    double account = 0;
    //创建锁
    ReentrantLock lock = new ReentrantLock();

    //存钱方法
    public void deposit(double cash) {
        if(account>0) {
            try {
                lock.lock();
                account += cash;
                //让线程阻塞一会，更好的观察共享数据的值
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()
                        + "向账户存入" + cash + "元,当前账户余额为：" + account + "元");
            } finally {
                lock.unlock();
            }
        }
    }
}

//客户类
class Consumer extends Thread {
    Account account;

    //通过构造方法传参，达到使用同一账户对象的效果
    Consumer(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            account.deposit(1000);
        }
    }
}